/*
 * RawMap Map Editor
 * Copyright 2010 RawMap developers (see AUTHORS file)
 *
 * This file is part of RawMap.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation; either version 2 of the License, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
 * Place, Suite 330, Boston, MA 02111-1307, USA.
 */

#include "window.h"
#include "ui_window.h"

#include <QtGui>

Window::Window(QWidget *parent) :
  QWidget(parent),
  ui(new Ui::Window)
{
  ui->setupUi(this);

  setWindowFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);

  createActions();
  createTrayIcon();

  widgetMask = QPixmap(QLatin1String(":/images/background"));

#ifdef WIN32
  alpha = 255;
  setMouseTracking(true);
  SetWindowLong(winId(), GWL_EXSTYLE, GetWindowLong(winId(), GWL_EXSTYLE)
                | WS_EX_LAYERED);
#endif

  connect(trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)),
           this, SLOT(iconActivated(QSystemTrayIcon::ActivationReason)));

  setWindowIcon(QIcon(QLatin1String(":/icons/rawpet")));
  trayIcon->setIcon(QIcon(QLatin1String(":/icons/rawpet")));

  restoreAction->setEnabled(false);

  trayIcon->show();

  QDesktopWidget *d = QApplication::desktop();

  setGeometry(d->width()-widgetMask.width(),d->height()-widgetMask.height()-30,
              widgetMask.width(), widgetMask.height());
}

Window::~Window()
{
  delete ui;
}

void Window::changeEvent(QEvent *e)
{
  QWidget::changeEvent(e);
  switch (e->type())
  {
  case QEvent::LanguageChange:
    ui->retranslateUi(this);
    break;
  default:
    break;
  }
}

void Window::closeEvent(QCloseEvent *e)
{
  if (trayIcon->isVisible())
  {
    hideWindow();
    e->ignore();
  }
}

void Window::createActions()
{
  hideAction = new QAction(tr("&Esconder"), this);
  connect(hideAction, SIGNAL(triggered()), this, SLOT(hideWindow()));

  restoreAction = new QAction(tr("&Restaurar"), this);
  connect(restoreAction, SIGNAL(triggered()), this, SLOT(restoreWindow()));

  quitAction = new QAction(tr("&Fechar"), this);
  connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit()));
}

void Window::createTrayIcon()
{
  trayIconMenu = new QMenu(this);
  trayIconMenu->addAction(hideAction);
  trayIconMenu->addAction(restoreAction);
  trayIconMenu->addSeparator();
  trayIconMenu->addAction(quitAction);
  trayIconMenu->setObjectName(QLatin1String("menu"));

  trayIcon = new QSystemTrayIcon(this);
  trayIcon->setContextMenu(trayIconMenu);
}

void Window::hideWindow()
{
  hideAction->setEnabled(false);
  restoreAction->setEnabled(true);
  hide();
}

void Window::restoreWindow()
{
  hideAction->setEnabled(true);
  restoreAction->setEnabled(false);
  showNormal();
}

void Window::iconActivated(QSystemTrayIcon::ActivationReason reason)
{
  switch (reason)
  {
  case QSystemTrayIcon::Trigger:
  case QSystemTrayIcon::DoubleClick:
    if(isVisible())
      hideWindow();
    else
      restoreWindow();
    break;
  default:
    break;
  }
}

QSize Window::sizeHint()
{
  return QSize(widgetMask.width(), widgetMask.height());
}

#ifdef WIN32
void Window::setLayered()
{
  SetWindowLong(winId(),GWL_EXSTYLE,GetWindowLong(winId(), GWL_EXSTYLE)
                | WS_EX_LAYERED);
}

void Window::mousePressEvent(QMouseEvent *event)
{
  childRegion = childrenRegion();
  if (!childRegion.contains(event->pos()))
  {
    if (event->button() == Qt::LeftButton)
    {
      dragPosition = event->globalPos() - frameGeometry().topLeft();
      event->accept();
    }
  }
}

void Window::mouseMoveEvent(QMouseEvent *event)
{
  if (event->buttons() & Qt::LeftButton)
  {
    move(event->globalPos() - dragPosition);
    event->accept();
  }
}

void Window::updateAlpha()
{
  HBITMAP oldBitmap;
  HBITMAP hBitmap;
  SIZE size;
  size.cx = widgetMask.width();
  size.cy = widgetMask.height();
  HDC screenDc = GetDC(NULL);
  POINT pointSource;
  pointSource.x = 0;
  pointSource.y = 0;
  POINT topPos;
  topPos.x = x();
  topPos.y = y();
  HDC memDc = CreateCompatibleDC(screenDc);
  BLENDFUNCTION blend;
  blend.BlendOp = AC_SRC_OVER;
  blend.BlendFlags = 0;
  blend.SourceConstantAlpha = alpha;
  blend.AlphaFormat = AC_SRC_ALPHA;
  hBitmap = widgetMask.toWinHBITMAP(QPixmap::PremultipliedAlpha);
  oldBitmap = (HBITMAP)SelectObject(memDc, hBitmap);
  UpdateLayeredWindow(winId(), screenDc,  &topPos,  &size, memDc,  &pointSource,
                      0, &blend, ULW_ALPHA);
  ReleaseDC( NULL, screenDc);
  if (hBitmap!=NULL)
  {
    SelectObject(memDc, oldBitmap);
    //DeleteObject(hBitmap);
    DeleteObject(hBitmap);
  }
  DeleteDC(memDc);
}

void Window::paintEvent(QPaintEvent *event)
{
  QPainter p(&widgetMask);
  QObjectList ol = children();
  foreach(QObject *o, ol)
  {
    if (o->isWidgetType() && o->objectName() != QLatin1String("menu"))
    {
      QWidget* child = qobject_cast<QWidget*>(o);
      p.drawPixmap(child->geometry(),drawCtrl(child ));
    }
  }
  p.end();
  updateAlpha();
}

QPixmap Window::drawCtrl(QWidget * widget)
{
  if (!widget)
    return QPixmap();

  QRect r(widget->rect());
  QPixmap res(r.size());
  widget->render(&res,-r.topLeft(),r,QWidget::DrawWindowBackground
                 | QWidget::DrawChildren | QWidget::IgnoreMask);

  return res;
}
#endif
